/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package huetari_48;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import org.jdom2.JDOMException;
/**
 *El simulador es el encargado de permitirme interactuar con la logica que se maneja a nivel de juego,
 * esto para realizar pruebas y obtener un resultado visible.
 * @author kenneth
 */
public class Simulador implements IConstantes  
{
    AnalizadorSintactico analizadorSintactico;
    private Matriz matrizFichas = Matriz.getInstance(); //Instacia de la matriz que representa las fichas(SINGLETON)
    private InputStreamReader isr = new InputStreamReader(System.in);
    private BufferedReader br = new BufferedReader(isr);
    
    /*
     * El constructor recilbe la instancia del analizador sintactico que se utilizara
     */
    public Simulador(AnalizadorSintactico analizador)
    {
        analizadorSintactico=analizador;
    }
    
    /*
     * inicia el simulador, debo indicar la fila columna y nombre de ficha a insertar, debido a que es para
     * obtener unicamente un resultado visual no maneja exepciones.
     */
    public void iniciar() throws IOException, JDOMException 
    {
        int filaLeida;
        int columLeida;
        String nombreLeido;
        System.out.println(" ");
        System.out.println("Digite la fila, columna y nombre de ficha a insertar:");
        System.out.print("Fila: ");
        filaLeida = Integer.parseInt(br.readLine());
        System.out.print("Columna: ");
        columLeida=Integer.parseInt(br.readLine());
        System.out.print("Nombre de Ficha: ");
        nombreLeido=br.readLine();
        System.out.println(" ");
        validarCasilla(filaLeida,columLeida,nombreLeido);
    }
    
    /*
     * Metodo encargado de validar la casilla en la cual se desea poner una ficha, la primera validacion que
     * realiza es ver si la casilla esta ocupada, de estarlo ofrece al usuario la opcion de sustituir la ficha,
     * luego de haber analizado la casilla procede con ayuda de otro metodo a validar la posicion(sintaxis) de 
     * la ficha que se desea poner, este metodo tambien valida si existen requerimientos por parte de alguna 
     * ficha(los requerimientos se obtienen de la clase AnalizadorSintactico), de existir requerimientos este
     * metodo no permite seguir hasta cumplirlos.
     */
    private void validarCasilla(int fila, int columna, String ficha) throws IOException, JDOMException
    {
        String[] requerimientos = analizadorSintactico.ObtenerRequerimientosActuales();
        if(!((matrizFichas.getMatriz()[fila][columna]).equalsIgnoreCase(casillaNula)))
        {
            int opcion;
            System.out.println(" ");
            System.out.println(" ");
            System.out.println("La casilla seleccionada esta ocupada");
            System.out.println("Para sustituirla digite 1, sino digite 0");
            opcion=Integer.parseInt(br.readLine());
            System.out.println(" ");
            if(opcion==1)
            {
                validarPosicionFicha(fila,columna,ficha);
            }
        }
        else
            if(requerimientos[0].equalsIgnoreCase("")) // si no existen requerimientos se utiliza esta validacion porque del XML siempre se carga aunque sea un strgin nulo
            {
                validarPosicionFicha(fila,columna,ficha);
            }
            else
            {
                //Con ayuda del analisis sintactico se valida que se cumpla los requerimientos
                if(analizadorSintactico.analizarRequerimientosLed(matrizFichas.getMatriz(), fila, columna, ficha))
                {
                    validarPosicionFicha(fila,columna,ficha);
                }
                else
                    System.out.println("NO CUMPLE LOS REQUERIMIENTOS");
            }
        
        matrizFichas.imprimirMatriz();
        iniciar();
    }

    /*
     * Una vez analizada la casilla en la que se insertar la nueva ficha se valida la posicion que va a ocupar
     * esta utilizando para ello el analisis sintactico; primeramente se valida si las posiciones vecinas en las
     * que va a estar la nueva ficha estan vacias, de estarlo se inserta la ficha directamente.
     * Si las posiciones vecinas no estan vacias se procede a hacer el analisis sintactico sobre la nueva ficha
     * haciendo uso de la clase AnalizadorSintactico.
     */
    private void validarPosicionFicha(int fila,int colum,String ficha) throws JDOMException, IOException
    {
        boolean resultadoSintactico=true;
        if(validarEspaciosVacios(fila,colum))
        {
            matrizFichas.actualizarMatriz(fila,colum,ficha);
        }
        else
        {
            resultadoSintactico=analizadorSintactico.validarSintaxisDePosicion(matrizFichas.getMatriz(), fila,colum,ficha);
            if(resultadoSintactico)
            {
                matrizFichas.actualizarMatriz(fila,colum,ficha);
            }
            else
            {
                System.out.println("");
                System.out.println("ERROR: no puede colocar esa ficha en esa posicion");
                analizadorSintactico.eliminarRequerimientos();
                System.out.println("");
                iniciar();
            }
        }
    }
    
    /*
     * Metodo encargado de validar si las posiciones vecinas de una determinada casilla estan vacias.
     */
    private boolean validarEspaciosVacios(int fila, int colum)
    {
        boolean valida=true;
        try 
        {
            for(int contador=0;contador<contactosFicha;contador++)
            {
                if(contador==0 && !(matrizFichas.getMatriz()[fila+1][colum].equalsIgnoreCase(casillaNula)))
                    valida=false;
                else if(contador==1 && !(matrizFichas.getMatriz()[fila-1][colum].equalsIgnoreCase(casillaNula)))
                    valida=false;
                else if(contador==2 && !(matrizFichas.getMatriz()[fila][colum+1].equalsIgnoreCase(casillaNula)))
                    valida=false;
                else if(contador==3 && !(matrizFichas.getMatriz()[fila][colum-1].equalsIgnoreCase(casillaNula)))
                    valida=false;
                else{}
            }
	}
	catch (NullPointerException npe) {
	  }
         catch( ArrayIndexOutOfBoundsException e ) {}
        return valida;
    }
}
